{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p style=\"text-align: center;font-size: 33px;font-weight:bold;\"> <span style=\"color:DarkGoldenrod\">&lt;&lt;内存管理与常用数据结构&gt;&gt;</span></p>\n",
    "<p style=\"text-align: center;font-size: 25px;font-weight:bold;\"> <span style=\"color:Goldenrod\">&lt;&lt; Memory Management and Normal Data Structures  &gt;&gt;</span></p>\n",
    "<p style=\"text-align: right; font-size:15px; font-weight:normal\">----学而时习之，不亦乐乎？</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* **1、内存管理示意与相关变量声明**\n",
    "* **2、常用数据结构** \n",
    " * **2.1链表**\n",
    " * **2.2栈与队列**\n",
    " * **2.3树**\n",
    " * **2.4图**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1.1 内存管理示意**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![链表](./Resources/c-memory.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1.2 相关的变量声明**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//函数栈区变量\n",
    "int func(int a,int b){\n",
    "    int c;     //局部变量\n",
    "    char  s[20]; //局部变量数据\n",
    "    c = a+b;\n",
    "    return c;\n",
    "} //参数a,b;变量c;数组变量s[0~19]将存放于func的函数栈区。\n",
    "int main(){             // 运行过程\n",
    "    double d;           // 变量d存放于main函数的函数栈区。  \n",
    "    int c=func(3,4);    // 函数调用，意为着在内存中为func函数开辟栈区并执行函数。\n",
    "                        // 当函数执行完毕后，函数栈被撤销(所有局部变量占用的内存被回收)，只将结果返回（return）给上一个栈。\n",
    "    printf(\"%d\\n\",c);   // c=7.由return语句被执行时给定的值确定。\n",
    "        c=func(5,6);    // 再为func开辟一次栈区，与上次为func函数开辟的栈区不同。\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <malloc.h>\n",
    "//堆区内存申请。\n",
    "struct Student{\n",
    "    int id;\n",
    "    float score;\n",
    "    char name[40];\n",
    "} // 类型声明，未声明变量则不分配内存。\n",
    "\n",
    "struct Student* Create_Student(){   void* \n",
    "    struct Student* ps=(struct Student*) malloc(sizeof(struct Student)); //使用malloc函数向堆区申请内存，存放一个struct Student\n",
    "                                                                         //类型的变量。\n",
    "                        //强制类型转换\n",
    "    static struct Studnet st1;\n",
    "    struct Student* ps=&st1;                             \n",
    "    \n",
    "    return ps;\n",
    "}//函数声明，未被执行。\n",
    "int main(){\n",
    "    struct Student* ps = Create_Student(); // 执行函数，将结果返回，为malloc函数运行返回的地址。  \n",
    "   \n",
    "    free(ps);                              // 释放内存。\n",
    "    return -1;\n",
    "}\n",
    "\n",
    "//堆区内存操作函数。          void func(...);     void* i;     \n",
    "/*\n",
    "extern void* malloc (unsigned int num_bytes); //向操作系统申请多少个byte。 \n",
    "void  free(void* p); p=NULL;                  //内部机制不管,释放内存结束后，p变为野指针。\n",
    "void* calloc(size_t nelem, size_t elsize);    //malloc的简单封装，=malloc(nelem*elsize)。    malloc(100) ->p*  \n",
    "void  relloc(void* __ptr,size_t );            //对于 __ptr指针指向的地质从新申请内存。可能会改写__ptr地址。relloc(p,1000);\n",
    "*/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//全局变量与静态变量。\n",
    "#include <stdio.h>\n",
    "int ga=3,gb=4;  // a,b 出现在任意函数前，为全局变量。？为啥又称为自动变量？ \n",
    "int* p;\n",
    "\n",
    "int func(int a,int b int c){\n",
    "    // a, b , c\n",
    "    // ga,gb.\n",
    "}\n",
    "\n",
    "void add(int a,int b){\n",
    "    int c;\n",
    "    c = a+b;\n",
    "    p = &c;\n",
    "} // c定义为静态变量，则存放于永久存储区。当函数栈销毁后，虽不可见，却在内存中真实存在。\n",
    "\n",
    "int main(){\n",
    "    add(a,b);            //调用add函数，以全局变量a,b为参数。\n",
    "    printf(\"%d\\n\",*p);   //根据地址，访问静态变量c的值。    \n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//常量、常变量、初始化字符串。\n",
    "#define m_pi 3.145926    //使用预编译指令作同名替换，不涉及内存管理。 \n",
    "const char c = 'a';      //常变量。占内存，常用来作参数保护。 sizeof(c) =1; c=\n",
    "int func(const int* a);     int func(int a[])==int func(const int* a);\n",
    "\n",
    "char* p=\"Hello C!\";      //未直接声明为常量\n",
    "p[1] = 'a';              //可正常编译，但运行时有错误。 初始化字符指针的字符串不可更改。 \n",
    "\n",
    "char ps[]= \"Hello C!\"    // = char ps[]={'H','e','l','l','o',' ','C','!','\\0'}。一定要注意串尾结束符‘\\0’。\n",
    "ps[1] = 'b';    \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2.1 链表**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![链表](./Resources/LinkList.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//ANSI C,\n",
    "//C89. \n",
    "#include <stdio.h>\n",
    "#include <malloc.h>\n",
    "struct Data{\n",
    "int no;\n",
    "};\n",
    "//基本类型定义,从整体结构中的单个节点出发\n",
    "struct LinkList{\n",
    "    struct Data*     data;                       // 单个元素中的数据  \n",
    "    struct LinkList* next;                       // 指向表中下一个元素\n",
    "};\n",
    "struct LinkList* linklist=NULL;          //声明一个表头指针。                            \n",
    "struct LinkList* c=NULL;      // \n",
    "struct LinkList* p=NULL; //C89,c99.\n",
    "int i;\n",
    "//相关操作\n",
    "//1. 向表尾添加数据    \n",
    "void append_list(struct LinkList* list,struct LinkList* p){\n",
    "//struct LinkList* p;\n",
    "\tif(list==NULL) return;\n",
    "     //ANSI C C99.\n",
    "for(;list->next!=NULL;list=list->next);                                          //找到表尾,预留表头\n",
    "list->next=p;                                                                    //接入新结点到表尾\n",
    "}\n",
    "//2. 按要求查找表节点    \n",
    "struct LinkList* find(struct LinkList* list,int number){\n",
    "    \n",
    "for(;list->data->no!=number&&list->next!=NULL;list=list->next);\n",
    "if(list->data->no!=number) return NULL; //确定达到表尾且表尾数据不符合要求。\n",
    "    else return list;\n",
    "}\n",
    "//2.1 按要求查找表节点的前一个元素\n",
    "struct LinkList* find_p(struct LinkList* list,int number){\n",
    "if(list==NULL||list->next==NULL) return NULL;\n",
    "for(;list->next->data->no!=number;list=list->next);\n",
    "if(list->next==NULL) return NULL; //确定达到表尾\n",
    "else return list;\n",
    "}\n",
    "\n",
    "//3. 删除表中节点p的下一个节点。\n",
    "void del_next(struct LinkList* p){\n",
    "if(p==NULL) return;\n",
    "c=p->next; \n",
    "    if(c==NULL) return;  //表尾节点没有下一个节点\n",
    "    else{\n",
    "    p->next =c->next;\n",
    "\tfree(c->data);\n",
    "    free(c);    \n",
    "    }\n",
    "}\n",
    "\n",
    "void add_next(struct LinkList* p,struct LinkList* n){\n",
    "if(p==NULL) return;\n",
    "n->next=p->next;\n",
    "p->next=n;\n",
    "}\n",
    "\n",
    "void modify_next(struct LinkList* p, int number){\n",
    "if(p==NULL||p->next==NULL) return;\n",
    "p->next->data->no=number;\n",
    "}\n",
    "\n",
    "\n",
    "//4. 销毁整个链表\n",
    "void destory_list(struct LinkList* list){\n",
    "    if(list==NULL) return;\n",
    "    while(list->next!=NULL) del_next(list);\n",
    "    //free(list); //回收在堆区申请的内存。\n",
    "}\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "int main(){\n",
    "//struct LinkList* p;\n",
    "//test LinkList    \n",
    "\t//while(i<100){...}\n",
    "\t//do{}while(i<100)\n",
    "linklist=(struct LinkList*)malloc(sizeof(struct LinkList));\t\n",
    "linklist->data  =(struct Data*) malloc(sizeof(struct Data));\n",
    "linklist->data->no=-1;\n",
    "linklist->next=NULL;  //important!\n",
    "for(i=1;i<10;i++){\n",
    "    p = (struct LinkList*)malloc(sizeof(struct LinkList)); \n",
    "    p->data  =(struct Data*) malloc(sizeof(struct Data));\n",
    "\tp->data->no=i;\n",
    "\tp->next=NULL;\n",
    "//scanf(\"Please input number：%u\\n\",&((p->data).no));\n",
    "//scanf(\"Please input name:%s\\n\",(p->data).name); \n",
    "    append_list(linklist,p);\n",
    "    //......scanf其他\n",
    "}\n",
    "for(p=linklist->next;p!=NULL;p=p->next) printf(\"%d \",p->data->no);printf(\"\\n\");\n",
    "p=find_p(linklist,8);\n",
    "del_next(p);\n",
    "for(c=linklist->next;c!=NULL;c=c->next) printf(\"%d \",c->data->no);printf(\"\\n\");\n",
    "c=(struct LinkList*) malloc(sizeof(struct LinkList));\n",
    "c->data=(struct Data* ) malloc(sizeof(struct Data));\n",
    "c->data->no=8;\n",
    "c->next=NULL;\n",
    "add_next(p,c);\n",
    "for(c=linklist->next;c!=NULL;c=c->next) printf(\"%d \",c->data->no);printf(\"\\n\");\n",
    "modify_next(p,66);\n",
    "for(c=linklist->next;c!=NULL;c=c->next) printf(\"%d \",c->data->no);printf(\"\\n\");\n",
    "destory_list(linklist);    //一定要记得销毁整个链表。\n",
    "free(linklist->data);\n",
    "free(linklist);\n",
    "\n",
    "//其他操作。\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2.2 栈与队列**<br>\n",
    "**栈：**先进后出的数据集合<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![栈](./Resources/stack_illu.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**队列：**先进先出的数据结合<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![队列](./Resources/queue-illu.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//基本类型定义\n",
    "#include <stdio.h>\n",
    "#define MaxE 200\n",
    "struct Data{\n",
    "    int no;\n",
    "};\n",
    "typedef struct {                                            //重要数据结构，先进后出\n",
    "              struct Data datas[MaxE]; \n",
    "              int top;                                     //栈中最后一条数据在数组中的的序号 \n",
    "} Stack;                \n",
    "\n",
    "//相关操作（类型行为）  // int a; int& b=a;  \n",
    "struct Data pop_stack(Stack* s){                                  // 弹栈, Sorry 记混了，类型& 同名定义是C++特有语法。\n",
    "    if(s->top<0) return  ;\n",
    "    return(s->datas[s->top--]);                                     // 关键语句\n",
    "} \n",
    " \n",
    "//top \n",
    "void push_stack(Stack* s, struct Data data){                      // 压栈\n",
    "    if(s->top>=200-1) return;\n",
    "    s->datas[++s->top]=data;                                      // 关键语句\n",
    "    \n",
    "}\n",
    "int is_Stack_Empty(Stack* s){\n",
    "if(s->top<0) return 1;\n",
    "else return 0;\n",
    "}\n",
    "                                         \n",
    "int main(){\n",
    "Stack st; st.top=-1;                                            //声明变量,常规类型声明下需要添加struct关键字， \n",
    "int i;\n",
    "//struct Data data;data.feature1=......;                        // 生明数据变量、数据变量赋值。\n",
    "//push_stack(&st,data);                                         // 压数据入栈    \n",
    "//codes....\n",
    "for(i=0;i<5;i++){\n",
    "    struct Data d;\n",
    "    d.no=i;\n",
    "    push_stack(&st,d);\n",
    "}\n",
    "\n",
    "    while(!is_Stack_Empty(&st)) {                               // 弹除栈顶元素  \n",
    "    struct Data d=pop_stack(&st);\n",
    "    printf(\"%d\\n\",d.no);\n",
    "    }\n",
    "    return -1;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//队列的数据实现\n",
    "#include <stdio.h>    //for printf\n",
    "#include <malloc.h>   //for malloc\n",
    "#include <memory.h>   //for memset\n",
    "//1 数组形式队列的实现\n",
    "#define __MaxQElements 100         //作文章，如果需要超大数组（超出内存限制）怎么解决？\n",
    "#define __DataType     int         //当使用其他类型的数据时，修改此行。\n",
    "#define __ERROR        -9999\n",
    "typedef struct { //数组形式,一般在结构体定义内部不设初值。\n",
    "    __DataType arr[__MaxQElements];\n",
    "    int front;\n",
    "    int rear;\n",
    "    unsigned int size;\n",
    "} Queue_Arr;     //使用typedef 结合struct 定义Queue_Arr结构体类型。\n",
    "//使用指针初始化结构体。 类型& 引用是C++的语法。C语言一般只用指针。\n",
    "void init_QueueArr(Queue_Arr* queue){   //&放在类型后面，声明函数参数与传入函数的变量为同名关系\n",
    "    memset(queue->arr,0,__MaxQElements); //初始化数据，能用标准头文件定义的函数就用之\n",
    "    queue->front=-1;                     //空队，队头不指向任何数据\n",
    "    queue->rear =-1;                     //空队，队尾不指向任何数据\n",
    "    queue->size = 0;                   //空队，数据数为零\n",
    "}\n",
    "//不需要destory_QueueArr, 为般什么？\n",
    "int  isempty_QueueArr(Queue_Arr* queue){ //判断队列是否为空，正常来说空满队判断函数是不应该暴露的接口（回忆Java中的接口）\n",
    "    if(queue->size==0) return 1;\n",
    "    else return 0;\n",
    "}\n",
    "void en_QueueArr(Queue_Arr* queue,__DataType data){\n",
    "    if((queue->size+1)>__MaxQElements){\n",
    "        printf(\"The Queue have been full!Can't put in any datas\");\n",
    "        return;\n",
    "    }\n",
    "    queue->arr[(++queue->size,++queue->rear)%__MaxQElements]=data; //回忆逗号式子，能写一行就一行。    \n",
    "}\n",
    "__DataType de_QueueArr(Queue_Arr* queue){\n",
    "    if(isempty_QueueArr(queue)) {\n",
    "        printf(\"The QueueArr have been Empty, count not dequeue anything!\\n\"); \n",
    "        return __ERROR;\n",
    "    }\n",
    "    return queue->arr[(--queue->size,++queue->front)%__MaxQElements]; //数据出队。\n",
    "}  //以上队列的定义依然不够完整，至少-9999作为数据不能入队。请尝试改进。写程序应格外当心，确保一次书写，什么时候都能用。\n",
    "\n",
    "int main(){\n",
    "    Queue_Arr queue;\n",
    "    init_QueueArr(&queue);\n",
    "    en_QueueArr(&queue,5);\n",
    "    en_QueueArr(&queue,3);\n",
    "  //  printf(\"%d\\n\",de_QueueArr(&queue));\n",
    "  //  printf(\"%d\\n\",de_QueueArr(&queue));\n",
    "  //  printf(\"%d\\n\",de_QueueArr(&queue));\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//队列的链表实现\n",
    "#include <stdio.h>    //for printf\n",
    "#include <malloc.h>   //for malloc\n",
    "#include <memory.h>   //for memset\n",
    "//1 链表形式队列的实现\n",
    "//#define __MaxQElements 100       //链表形式只需要考虑内存是否够用，不需要定义。\n",
    "#define __DataType     int         //当使用其他类型的数据时，修改此行。\n",
    "\n",
    "typedef struct Q_Element{          //链表中的元素需要指向下一个元素。\n",
    "    __DataType data;\n",
    "    struct Q_Element* next;\n",
    "} Q_Element;\n",
    "\n",
    "typedef struct {\n",
    "    Q_Element* front;\n",
    "    Q_Element* rear;\n",
    "} Queue_Lnk;\n",
    "\n",
    "Q_Element* create_QElement(__DataType t){\n",
    "    Q_Element* p=(Q_Element*) malloc(sizeof(Q_Element));\n",
    "    p->data=t;\n",
    "    return p;\n",
    "}\n",
    "Queue_Lnk* create_QueueLnk(){\n",
    "    Queue_Lnk* queue = (Queue_Lnk*) malloc(sizeof(Queue_Lnk));\n",
    "    return (queue->front=queue->rear=NULL,queue);\n",
    "}\n",
    "int isempty_QueueLnk(Queue_Lnk* queue){\n",
    "    if(queue->front==NULL&&queue->rear==NULL) return 1;\n",
    "    else return 0;\n",
    "}\n",
    "void en_QueueLnk(Queue_Lnk* queue,Q_Element* ele){\n",
    "    if(isempty_QueueLnk(queue)) queue->front=queue->rear=ele; //第一个元素入队，特殊性。\n",
    "    else queue->rear->next=ele, queue->rear=ele; //一般情况，队尾添加元素，队尾指向最后。\n",
    "}\n",
    "Q_Element* de_QueueLnk(Queue_Lnk* queue){\n",
    "    if(isempty_QueueLnk(queue)) return NULL;        //空队返回空指针，（void*）应该叫无类型指针。\n",
    "    Q_Element* temp = queue->front;                 //取出队头。\n",
    "    if(queue->front==queue->rear)                   //如果队列中只有一个元素 \n",
    "    return (queue->front=queue->rear=NULL,temp);    //再回忆一次逗号表达式。以上均为特殊情况。 \n",
    "    return (queue->front=queue->front->next,temp);  //正常情况。队首指向下一个元素。    \n",
    "}\n",
    "\n",
    "int main(){\n",
    "    Queue_Lnk* queue=create_QueueLnk();\n",
    "    int i; \n",
    "    //入队、出队测试\n",
    "    for(i=0;i<100;i++) //C89不支持在for循环中初始化变量。\n",
    "        en_QueueLnk(queue,create_QElement(i));  \n",
    "    while(!isempty_QueueLnk(queue))\n",
    "        printf(\"%d\\n\",de_QueueLnk(queue)->data);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2.3 二叉树**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 起源于经典程序设计中广泛采纳的**二分（分治）思想**。\n",
    "2. 试图以与**二分（分治）思想**相似的数据组织方式简化工程实践。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![二叉树](./Resources/tree-illu.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A->B->D->E->G->C->F->H->\n",
      "D->B->E->G->A->C->H->F->\n",
      "D->G->E->B->H->F->C->A->\n",
      "A->B->C->D->E->F->G->H->\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[C kernel] Executable exited with code -11"
     ]
    }
   ],
   "source": [
    "//  D B E G A C H F  （树的中序遍历）\n",
    "\n",
    "//  A B D E G C F H   （树的前序遍历）\n",
    "  \n",
    "//  D G E B H F C A   (树的后序遍历)\n",
    "\n",
    "//  A B C D E F G H   (数的层序遍历)\n",
    "\n",
    "//二叉树，演示\n",
    "#include <stdio.h>                 //for printf\n",
    "#include <malloc.h>                //for malloc\n",
    "#include <memory.h>                //for memset\n",
    "#define __DataType    char         //当使用其他类型的数据时，修改此行。\n",
    "__DataType datas[]={'A','B','C','D','E','\\0','F','\\0','\\0','\\0','G','\\0','\\0','H','\\0'};\n",
    "int i;\n",
    "typedef struct T_Node{\n",
    "    __DataType data;\n",
    "    struct T_Node* left;\n",
    "    struct T_Node* right;\n",
    "} T_Node;\n",
    "\n",
    "T_Node* create_Tree(__DataType datas[],int max,int num){ //回忆递归。\n",
    "    if(num>max) return NULL;\n",
    "    __DataType data=datas[num];\n",
    "    if(data=='\\0') return NULL;\n",
    "    T_Node* root = (T_Node*) malloc(sizeof(T_Node));\n",
    "    root->data   = data;\n",
    "    root->left   = create_Tree(datas,max,num*2+1);\n",
    "    root->right  = create_Tree(datas,max,num*2+2);\n",
    "    return root;\n",
    "}\n",
    "//先序遍历。\n",
    "void F_Visit(T_Node* root ){\n",
    "    if(root==NULL) return;\n",
    "    printf(\"%c->\",root->data);\n",
    "    F_Visit(root->left);\n",
    "    F_Visit(root->right);\n",
    "    \n",
    "}\n",
    "//中序遍历\n",
    "void M_Visit(T_Node* root){\n",
    "    if(root!=NULL){\n",
    "        M_Visit(root->left);\n",
    "        printf(\"%c->\",root->data);\n",
    "        M_Visit(root->right);\n",
    "    }\n",
    "}\n",
    "//后序遍历\n",
    "void L_Visit(T_Node* root){\n",
    "    if(root!=NULL){\n",
    "        L_Visit(root->left);\n",
    "        L_Visit(root->right);\n",
    "        printf(\"%c->\",root->data);\n",
    "    }\n",
    "}\n",
    "//层序遍历，需要使用队列  贴以便稍微修改\n",
    "//1 数组形式队列的实现\n",
    "#define __MaxQElements 100         //作文章，如果需要超大数组（超出内存限制）怎么解决？\n",
    "#define __QDataType    T_Node*     //当使用其他类型的数据时，修改此行。\n",
    "#define __ERROR        NULL\n",
    "typedef struct { //数组形式,一般在结构体定义内部不设初值。\n",
    "    __QDataType arr[__MaxQElements];\n",
    "    int front;\n",
    "    int rear;\n",
    "    unsigned int size;\n",
    "} Queue_Arr;     //使用typedef 结合struct 定义Queue_Arr结构体类型。\n",
    "//使用指针初始化结构体。 类型& 引用是C++的语法。C语言一般只用指针。\n",
    "void init_QueueArr(Queue_Arr* queue){   //&放在类型后面，声明函数参数与传入函数的变量为同名关系\n",
    "    memset(queue->arr,0,__MaxQElements); //初始化数据，能用标准头文件定义的函数就用之\n",
    "    queue->front=-1;                     //空队，队头不指向任何数据\n",
    "    queue->rear =-1;                     //空队，队尾不指向任何数据\n",
    "    queue->size = 0;                   //空队，数据数为零\n",
    "}\n",
    "//不需要destory_QueueArr, 为般什么？\n",
    "int  isempty_QueueArr(Queue_Arr* queue){ //判断队列是否为空，正常来说空满队判断函数是不应该暴露的接口（回忆Java中的接口）\n",
    "    if(queue->size==0) return 1;\n",
    "    else return 0;\n",
    "}\n",
    "void en_QueueArr(Queue_Arr* queue,__QDataType data){\n",
    "    if((queue->size+1)>__MaxQElements){\n",
    "        printf(\"The Queue have been full!Can't put in any datas\");\n",
    "        return;\n",
    "    }\n",
    "    queue->arr[(++queue->size,++queue->rear)%__MaxQElements]=data; //回忆逗号式子，能写一行就一行。    \n",
    "}\n",
    "__QDataType de_QueueArr(Queue_Arr* queue){\n",
    "    if(isempty_QueueArr(queue)) {\n",
    "        printf(\"The QueueArr have been Empty, count not dequeue anything!\\n\"); \n",
    "        return __ERROR;\n",
    "    }\n",
    "    return queue->arr[(--queue->size,++queue->front)%__MaxQElements]; //数据出队。\n",
    "}  //以上队列的定义依然不够完整，至少-9999作为数据不能入队。请尝试改进。写程序应格外当心，确保一次书写，什么时候都能用。\n",
    "\n",
    "void C_Visit(T_Node* root){\n",
    "    Queue_Arr* queue;\n",
    "    en_QueueArr(queue,root);\n",
    "    while(!isempty_QueueArr(queue)){\n",
    "        root=de_QueueArr(queue);\n",
    "        printf(\"%c->\",root->data);\n",
    "        if(root->left!=NULL) en_QueueArr(queue,root->left);\n",
    "        if(root->right!=NULL) en_QueueArr(queue,root->right);\n",
    "    }\n",
    "}\n",
    "\n",
    "int main(){\n",
    "    T_Node* root=create_Tree(datas,15,0);\n",
    "    F_Visit(root),printf(\"\\n\");\n",
    "    M_Visit(root),printf(\"\\n\");\n",
    "    L_Visit(root),printf(\"\\n\");\n",
    "    C_Visit(root),printf(\"\\n\");\n",
    "    return -1;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//  A B D E G C F H   （树的前序遍历）\n",
    "//  D B E G A C H F  （树的中序遍历）\n",
    "//  D G E B H F C A   (树的后序遍历)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C",
   "language": "c",
   "name": "c"
  },
  "language_info": {
   "file_extension": ".c",
   "mimetype": "text/plain",
   "name": "c"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
